
#include "BuildConfig.h"
#include "Bsp.h"
#include "systick.h"
#include "LedId.h"

#include "custom_hid_core.h"
#include "USB_HID.h"
#include "BSP_Uart.h"
#include "fifo.h"
#include "Transfer.h"

/*
1.抗干扰
2.大块传输
3.多通道
*/

//	void Bsp_InByte(uint8_t channel, uint8_t ch);

static uint32_t randSeed;

static uint8_t commChannel = 0;
static uint8_t commRxBuffer[256];
static fifo_t commRxFifo = {
	commRxBuffer,
	sizeof(commRxBuffer),
	0,0
};
static volatile uint32_t ledFlashFreq;
volatile uint32_t rxTick;
volatile uint32_t timerTick;
static volatile uint32_t runCount;

void Bsp_InByte(uint8_t channel, uint8_t ch);

static int Bsp_CommLock(uint8_t channel){
	if(!commChannel){
		commChannel = channel;
	}

	return commChannel;
}

void Bsp_ReceieCallback(uint8_t ch){
	if(Bsp_CommLock(2) == 2){
		rxTick = 2;
		Transfer_RxCallback(&ch, 1);
		BSP_Led_SetState(LedId_Red, 1);
	}
}

void Bsp_HidRxCallback(uint8_t* buf, uint8_t len){
	if(Bsp_CommLock(1) == 1){
		rxTick = 20;
		Transfer_RxCallback(buf, len);		
		BSP_Led_SetState(LedId_Red, 1);
	}
}


void Bsp_TimerTick(void){
	timerTick++;
	if(rxTick){
		if(--rxTick == 0){
			Transfer_Reset();
		}
	}
	
	if(runCount == 0){
		BSP_Led_SetState(LedId_Red, (timerTick & 0x100) ? 1 : 0);
	}
	else{
		runCount--;
	}
}


/*
初始化硬件
*/
void Bsp_Init(void) {
	runCount = 0;
	timerTick = 0;
	systick_config();
//		BSP_Timer_Init(Bsp_TimerTick);
//		BSP_Timer_Start();
}

//
void BSP_UpgrageInit(void){
    rcu_periph_clock_enable(RCU_AF);	
	gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
	BSP_Led_Init();
	BSP_Uart_SetRxCallback(2, Bsp_ReceieCallback);
	BSP_Uart_Init(2);
	BSP_Led_SetState(LedId_Red, timerTick & 0x80);
	BSP_USB_Init();
	USB_HID_Init();
	custom_hid_set_callback(Bsp_HidRxCallback);
}


void BSP_GPIO_Deinit(void){
	static const uint32_t gpios[] = {
		GPIOA,
		GPIOB,
		GPIOC,
		GPIOD,
		GPIOE,
		GPIOF,
		GPIOG,
	};
	int i;
	
	gpio_afio_deinit();
	for(i = 0; i < sizeof(gpios)/sizeof(gpios[0]); i++){
		gpio_deinit(gpios[i]);
	}
}

void BSP_UpgradeDeinit(void){
	SysTick->CTRL = 0;
	BSP_GPIO_Deinit();
	BSP_Uart_Deinit(2);
	BSP_USB_Deinit();
}

int BSP_CheckPlug(void){
	return USB_IsPlugged();
}


void BSP_RunState(uint8_t state){
	runCount = 2000;
	BSP_Led_SetState(LedId_Red, state);
}

#if 0
uint8_t Bsp_GetUid(uint32_t uid[3]){
	uid[0] = *(__IO uint32_t*)(0x1FFFF7E8);
	uid[1] = *(__IO uint32_t*)(0x1FFFF7EC);
	uid[2] = *(__IO uint32_t*)(0x1FFFF7F0);
	return 12;
}
#endif 

/*
获取随机种子
*/
uint32_t Bsp_GetSeed(void){
	return randSeed;
}

void Bsp_Seed(void){
	randSeed += 31;
}

uint32_t Bsp_Tick(void){
	return timerTick;
}

/*
发送一个字节
*/
void Bsp_SendByte(uint8_t ch){
	if(commChannel == 1){
		HID_SendByte(ch);
	}
	else
	if(commChannel == 2){
		BSP_Uart_Send(2, ch);
	}
}

void Bsp_SendBuf(const uint8_t buf[], uint32_t len){
	uint32_t i;
	for(i = 0; i < len; i++){
		Bsp_SendByte(buf[i]);
	}
}

/*
接收一个字节
*/
int Bsp_Receive(uint8_t* ch, uint32_t timeOut){
	uint32_t time = timerTick;
	
	while(Fifo_GetDataLength(&commRxFifo) == 0){
		randSeed++;
		if((timerTick - time) > timeOut){
			return 1;
		}
	}
	Fifo_GetOne(&commRxFifo, ch);
	return 0;
}

/*
清除发送缓存
*/
void Bsp_Flush(void){
	if(commChannel == 1){
		HID_Flush();
	}
}
/*
从一个channel 接收一个字节，并放入接收缓冲区
*/
void Bsp_InByte(uint8_t channel, uint8_t ch){
	if(!commChannel){
		commChannel = channel;
	}

	if(commChannel == channel){
		Fifo_PutOne(&commRxFifo, &ch);
	}
}

void Delay(volatile uint32_t nCount) {
    for (; nCount != 0; nCount--);
}


